﻿using System;

namespace DotNet.HowToUseInterfacesDemo.PoorUse
{
    /**************************************************************************
    **  The biggest misuse of interfaces I've seen is when they serve no 
    **  purpose. For example, the very large project at my work which
    **  was written almost 12 years ago has interfaces built for just about 
    **  everything! It's a nightmare. They also don't follow the .net naming
    **  convention of the preceding "I". They do, what I've seen more of in Java
    **  where the interface is named something like "Product" and the implemen-
    **  tation is name "ProductImpl". 
    **************************************************************************/
    public interface IPerson
    {
        string FristName { get; set; }
        string LastName { get; set; }
    }

    public class Person : IPerson
    {
        public string FristName { get; set; }
        public string LastName { get; set; }
    }

    /**************************************************************************
    **  The next biggest misuse of interfaces I've seen is the interfaces that 
     *  contain every method of the class which impliments it. Interfaces should
     *  be used as an abstraction point. They should be able to be reused. If
     *  we look at the interfase below, we could assume the contact person method
     *  first calls the FindEmailAddress to get the email, then calls the 
     *  SendEmailToPerson method. There is no reason for those to be in the inter-
     *  face. They should be internal methods.  If those were hidden then we 
     *  could impliment this interface with multiple was of contacting a person
    **************************************************************************/
    public interface IPersonContactor
    {
        void ContactPerson(IPerson person);
        string FindEmailAddress(IPerson person);
        void SendEmailToPerson(string emailAddress);
    }

    public class PersonContactor : IPersonContactor
    {
        public void ContactPerson(IPerson person)
        {
            var email = FindEmailAddress(person);
            SendEmailToPerson(email);
        }

        public string FindEmailAddress(IPerson person)
        {
            return String.Format("{0}.{1}@company.com", person.FristName, person.LastName).ToLower();
        }

        public void SendEmailToPerson(string emailAddress)
        {
            Console.WriteLine("Email sent to {0}", emailAddress);
        }
    }

    /**************************************************************************
    **  The last misuse of interfaces I've seen is instantiating the interface 
    **  with the derived class. This creates a dependency on the implemention 
    **  in a class that should only be dependent on the abstraction. I've seen
    **  this kinda usage over and over in production code. 
    **************************************************************************/
    class ImproperUseOfInterfaces
    {
        public static void StartHere()
        {
            IPerson person = new Person
            {
                FristName = "Jack",
                LastName = "Bauer"
            };

            IPersonContactor personContactor = new PersonContactor();
            personContactor.ContactPerson(person);
        }
    }
}
